package nl.cypherpunk.proLearner.rtsp;

import net.automatalib.words.Alphabet;
import net.automatalib.words.impl.Alphabets;
import nl.cypherpunk.proLearner.fuzzing.SUT;
import nl.cypherpunk.proLearner.rtsp.RTSPConfig;
import nl.cypherpunk.proLearner.rtsp.RTSPTestService;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

public class RTSPSUL implements SUT<String, String> {
    Alphabet<String> alphabet;
    public RTSPTestService rtsp;
    public RTSPSUL(RTSPConfig config) throws Exception {
        //alphabet = Alphabets.fromList(Arrays.asList(config.alphabet.split(" ")));

        rtsp = new RTSPTestService();

        rtsp.setTarget(config.target);
        rtsp.setHost(config.host);
        rtsp.setPort(config.port);
        rtsp.setCommand(config.cmd);
        rtsp.setRestartTarget(config.restart);
        rtsp.setReceiveMessagesTimeout(config.timeout);
        rtsp.setConsoleOutput(config.console_output);
        rtsp.setRedirectFile(config.redirectFile);
        //tls.setCoverageCmd(config.coverage_cmd);
        rtsp.setOutputDir(config.output_dir);
        File outputDir = new File(rtsp.outputDir + File.separator +"Seed");
        outputDir.mkdirs();
        File crashDir = new File(rtsp.outputDir + File.separator +"Crash");
        crashDir.mkdirs();
        rtsp.start();
    }

    public RTSPSUL(RTSPConfig config, int i) throws Exception {
        alphabet = Alphabets.fromList(Arrays.asList(config.alphabet.split(" ")));

        rtsp = new RTSPTestService();

        rtsp.setTarget(config.target);
        rtsp.setHost(config.host);
        rtsp.setPort(config.portList.get(i));
        rtsp.setCommand(config.cmdList.get(i));
        rtsp.setRestartTarget(config.restart);
        rtsp.setReceiveMessagesTimeout(config.timeout);
        rtsp.setConsoleOutput(config.console_output);
        rtsp.setRedirectFile(config.redirectFile);
        //tls.setCoverageCmd(config.coverage_cmd);
        rtsp.setOutputDir(config.output_dir);
        File outputDir = new File(rtsp.outputDir + File.separator +"Seed");
        outputDir.mkdirs();
        File crashDir = new File(rtsp.outputDir + File.separator +"Crash");
        crashDir.mkdirs();
        rtsp.start();
    }
    @Override
    public Alphabet<String> getAlphabet() {
        return Alphabets.fromList(rtsp.symbols);
    }

    public void exit()
    {
        rtsp.close();
    }

    public boolean canFork() {
        return false;
    }
    //change by pany
    public void setInitScore(Double score){
        rtsp.initScore = score;
    }

    public int getCoverage() throws IOException {
        return rtsp.getCoverage();
    }

    public String sendFuzzingMessage(byte[] message) throws Exception
    {
        return rtsp.sendFuzzingMessage(message);
    }
    public void saveMapper()
    {
        rtsp.saveMapper();
    }

    public byte[] getCurrent(){
        return rtsp.currentCase.get(rtsp.currentCase.size()-1);
    }
    @Override
    public int getTotalNum()
    {
        return rtsp.totalExecs;
    }
    @Override
    public boolean addMapper(String type, byte[] message){
        return rtsp.addMapper(type,message);
    }
    @Override
    public boolean delMapper(String subtype){
        return rtsp.delMapper(subtype);
    }
    @Override
    public Map<String, Integer> getSubtypes()
    {
        return rtsp.subtypes;
    }

    @Override
    public String messageToSymbol(byte[] message){
        String m="";
        try{
            m = new String(message,"utf-8");
        }
        catch(Exception e){
            e.printStackTrace();
        }
        String[] tmp = m.split(" ");
        return tmp[0];
    }

    @Override
    public int getIndexOfSymbol(byte[] message){
        String m="";
        try{
            m = new String(message,"utf-8");
        }
        catch(Exception e){
            e.printStackTrace();
        }
        String[] tmp = m.split(" ");
        return tmp[0].length()+1;
    }

    @Override
    public String step(String symbol) {
        String result = null;
        try {
            result = rtsp.processSymbol(symbol);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @Override
    public void pre() {
        try {
            rtsp.reset();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(0);
        }
    }

    @Override
    public void post() {
        try {
            rtsp.closeSocket();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(0);
        }
    }
}
